#include <graphics/BMPImageReader.h>
#include <graphics/ImageManager.h>

namespace ne
{
    ImagePtr BMPImageReader::loadImage(const std::string &fileName) const
    {
        FILE *file = fopen(fileName.c_str(), "rb");
        // make sure the file is there.
        if (file == 0)
        {
            std::cout << "File Not Found : " << fileName << std::endl;
            return ImagePtr();
        }

        // seek through the bmp header, up to the width/height:
        fseek(file, 18, SEEK_CUR);

        // read the width
        uint32_t width;
        if (!fread(&width, 4, 1, file))
        {
            std::cout << "Error reading width !\n";
            return ImagePtr();
        }

        // read the height 
        uint32_t height;
        if (!fread(&height, 4, 1, file))
        {
            std::cout << "Error reading height !\n";
            return ImagePtr();
        }

        // calculate the size (assuming 24 bits or 3 bytes per pixel).
        // read the planes
        uint16_t planes;          // number of planes in image (must be 1) 
        if (!fread(&planes, 2, 1, file))
        {
            std::cout << "Error reading planes !\n";
            return ImagePtr();
        }
        if (planes != 1)
        {
            std::cout << "Planes is not 1 !\n";
            return ImagePtr();
        }

        // read the bpp
        uint16_t bpp;             // number of bits per pixel (must be 24)
        if (!fread(&bpp, 2, 1, file))
        {
            std::cout << "Error reading bpp !\n";
            return ImagePtr();
        }

        uint32_t pixelSize = bpp / 8;
        PixelFormat format = PF_UNKNOWN;
        if (pixelSize == 1)
        {
            format = PF_ALPHA;
        }
        else if (pixelSize == 3)
        {
            format = PF_BGR;
        }
        else if (pixelSize == 4)
        {
            format = PF_BGRA;
        }

        // seek past the rest of the bitmap header.
        fseek(file, 24, SEEK_CUR);

        // read the data.
        ImagePtr pImage(ImageManager::GetSingleton().createImage(fileName, "ImageFiles", width, height, 1, format));
        
        byte *data = pImage->getData();
        uint32_t size = width * height * pixelSize;
        if (!fread(data, size, 1, file))
        {
            ImageManager::GetSingleton().removeByID(pImage->getID());
            pImage.setNull();
            std::cout << "Error reading image data from file!\n";
        }
        fclose(file);

        return pImage;
    }
}
